/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.cvut.fel.taskpro.view.controller;

import cz.cvut.fel.taskpro.business.imanager.IAssignmentBusiness;
import cz.cvut.fel.taskpro.business.support.BusinessRuleException;
import cz.cvut.fel.taskpro.data.entity.Template;
import cz.cvut.fel.taskpro.data.entity.TemplateFile;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;

/**
 * This controller is responsible for working with task. It provide create task
 * edit task, remove task or remove file with task.
 * @author Tom
 * @version 1.0.0. beta
 */
@ManagedBean(name = "taskBean")
@ViewScoped
public class TaskBean extends AbstractFileController implements Serializable {

    @ManagedProperty(value = "#{kantorTaskBean}")
    private KantroTaskController kantorTaskController;
    @EJB
    private IAssignmentBusiness assignmentB;
    private List<TemplateFile> filesWithTemplate;
    private List<TemplateFile> firstFilesWithTemplate;
    private Template selectTemplate;    
    private List<UploadedFile> files;
    private List<Template> kantorTemplates;
    private Template newTemplate; 
   private List<UploadedFile> assignmentFiles;
   private UploadedFile assignmentFile;
   /**
    * This method initialize class for use after construction. This method ask
    * business layer for get all template which were created by logged kantor. 
    * @see IAssignmentBusiness#getTemplateByKantor(cz.cvut.fel.taskpro.data.entity.Kantor) 
    */
    @PostConstruct
    public void init() {
        recognizeLogin();
        newTemplate = new Template();
        assignmentFiles = new ArrayList<UploadedFile>();
        files = new ArrayList<UploadedFile>();
        filesWithTemplate = new ArrayList<TemplateFile>();
        kantorTemplates = assignmentB.getTemplateByKantor(loggedKantor);
    }

    /**
     * This method call <code> create()</code> method in this class. Then
     * call {@linkplain KantroTaskController#templateAssign() } and return it.
     * If business rule exception is thrown then retrun string literal createTaskKantor
     * @return value from {@linkplain KantroTaskController#templateAssign() } or
     * literal createTaskKantor if business rule exception is invoke.
     */
    public String createTask() {
        try {
            create();
            return kantorTaskController.templateAssign();
        } catch (BusinessRuleException e) {
            printErrMessage(e.getExceptionCode(), e.getErrorMessage());
            return "createTaskKantor";
        }
    }
    /**
     * This method construct and aks business layer to add new template to database.
     * @see IAssignmentBusiness#addTemplate(cz.cvut.fel.taskpro.data.entity.Template) 
     */
    public void create() throws BusinessRuleException {
        newTemplate.setKantor(loggedKantor);
        newTemplate.setTemplateFiles(filesWithTemplate);
        assignmentB.addTemplate(newTemplate);
        assignmentFiles = new ArrayList<UploadedFile>();
        filesWithTemplate = new ArrayList<TemplateFile>();
        printSuccMessage("Task creation:", " The task name: " + newTemplate.getName() + " was successfully created");
        newTemplate = new Template();
    }
        /**
     * This method call <code> create()</code> method in this class. Then
     * reset kantor task bean by calling {@linkplain KantroTaskController#resetClass()  } and 
     * selected selectedTemplate to new created template.
     * If business rule exception is thrown then retrun string literal createTaskKantor
     * @return string assignTaskKantor if no exception is thrown, otherwise return
     * string createTaskKantor.
     */
    public String createAndAssign() {
        try {
            create();
            kantorTaskController.resetClass();
            Template[] templatesToAssign = new Template[1];
            //Template templateToAssign=assignmentB.
            kantorTaskController.setSelectedTemplate(templatesToAssign);
            return "assignTaskKantor";
        } catch (BusinessRuleException e) {
            printErrMessage(e.getExceptionCode(), e.getErrorMessage());
            return "createTaskKantor";
        }
    }
    /**
     * This method load files with template if new task is choose.
     */
    public void chooseNewTask() {
        filesWithTemplate = newTemplate.getTemplateFiles();
        firstFilesWithTemplate = new ArrayList<TemplateFile>(filesWithTemplate);
    }
    /**
     * This emthod ask business layer to modify template. New template and files with
     * first template are added to business layer
     * @see IAssignmentBusiness#modifyTemplate(cz.cvut.fel.taskpro.data.entity.Template, java.util.List) 
     */
    public void modifyTask() {
        try {
            assignmentB.modifyTemplate(newTemplate, firstFilesWithTemplate);
            printSuccMessage("Template: ", "The template was successfully changed.");
        } catch (BusinessRuleException ex) {
            printErrMessage(ex.getExceptionCode(), ex.getErrorMessage());
        }
    }
    //TODO remove -- test if can be removed first.
    public void handleFileUpload(FileUploadEvent event) throws IOException {
        assignmentFile = event.getFile();
        UploadedFile fileUpload = event.getFile();
        InputStream stream = event.getFile().getInputstream();
        File fileAddToTask = inputStreamToFile(stream, event.getFile().getFileName());
        TemplateFile newTemplateFile = new TemplateFile();
        newTemplateFile.setTemplate(newTemplate);
        newTemplateFile.setFile(fileUpload.getContents());
        newTemplateFile.setFileName(fileUpload.getFileName());
        newTemplateFile.setFileSize(fileUpload.getSize());
        filesWithTemplate.add(newTemplateFile);
        assignmentFiles.add(assignmentFile);
        files.add(fileUpload);
    }
    /**
     * This method remove template file from actual selected task. Only localy remove is made
     * no data or business layer action is called.
     */
    public void removeFile(TemplateFile templateFile) {
        Iterator fiIt = filesWithTemplate.iterator();
        int position = 0;
        while (fiIt.hasNext()) {
            TemplateFile curr = (TemplateFile) fiIt.next();
            if (curr.getId() == templateFile.getId()) {
                break;
            }
            position++;
        }
        filesWithTemplate.remove(position);
        printSuccMessage("File remove:", "The file " + templateFile.getFileName() + " was removed.");
    }
    /**
     * This method ask business layer to remove selected template. Then is removed from 
     * kantors created template in view.
     * @see IAssignmentBusiness#removeTemplate(cz.cvut.fel.taskpro.data.entity.Template) 
     */
    public void removeTask() {
        try {
            assignmentB.removeTemplate(newTemplate);
            kantorTemplates.remove(newTemplate);
            printSuccMessage("Remove task:", "The task " + newTemplate.getName() + " has been successfully removed");
        } catch (BusinessRuleException ex) {
            printErrMessage(ex.getExceptionCode(), ex.getErrorMessage());
        }
    }

    public Template getSelectTemplate() {
        return selectTemplate;
    }

    public void setSelectTemplate(Template selectTemplate) {
        this.selectTemplate = selectTemplate;
    }
    public void setKantorTaskController(KantroTaskController kantorTaskController) {
        this.kantorTaskController = kantorTaskController;
    }

    public List<TemplateFile> getFilesWithTemplate() {
        return filesWithTemplate;
    }

    public void setFilesWithTemplate(List<TemplateFile> filesWithTemplate) {
        this.filesWithTemplate = filesWithTemplate;
    }

    public List<UploadedFile> getFiles() {
        return files;
    }

    public void setFiles(List<UploadedFile> files) {
        this.files = files;
    }
     public List<Template> getKantorTemplates() {
        return kantorTemplates;
    }

    public void setKantorTemplates(List<Template> kantorTemplates) {
        this.kantorTemplates = kantorTemplates;
    }
    
    public Template getNewTemplate() {
        return newTemplate;
    }

    public void setNewTemplate(Template newTemplate) {
        this.newTemplate = newTemplate;
    }

    public List<UploadedFile> getAssignmentFiles() {
        return assignmentFiles;
    }

    public void setAssignmentFiles(List<UploadedFile> assignmentFiles) {
        this.assignmentFiles = assignmentFiles;
    }
     public UploadedFile getAssignmentFile() {
        return assignmentFile;
    }

    public void setAssignmentFile(UploadedFile assignmentFile) {
        this.assignmentFile = assignmentFile;
    }
}
